// 类型定义
interface _TreeNode {
  title: string;
  key: string;
  children?: _TreeNode[];
  isLeaf?: boolean;
}

// 定义树节点项的接口
interface TreeItem {
  id: string | number;
  parentId?: string | number;
  name: string;
  remark?: string;
  children?: TreeItem[];
  [key: string]: any; // 允许其他属性
}

// 定义映射对象的接口
interface ItemMap {
  [key: string]: TreeItem;
}

// 定义树节点的接口
interface TreeNode extends _TreeNode {
  remark?: string;
  data?: TreeItem;
}

// 定义图片项接口
interface ImageItem {
  url: string;
  id: number;
  status: string;
}

// 定义缓存Map的类型
const cacheMap = new Map<string, string[] | ImageItem[]>();

// 添加或移除 HTML 元素的类名
export function toggleHtmlClass(className: string): {
  add: () => void;
  remove: () => void;
} {
  /**
   * 添加类名到 HTML 元素
   */
  function add(): void {
    document.documentElement.classList.add(className);
  }

  /**
   * 从 HTML 元素移除类名
   */
  function remove(): void {
    document.documentElement.classList.remove(className);
  }

  return {
    add,
    remove,
  };
}

// 获取对象的所有键，支持嵌套对象
export function getKeys<T extends Record<string, unknown>>(
  obj: T,
  parentKeys: string[] = []
): string[] {
  let keys: string[] = [];

  for (const key in obj) {
    if (Object.prototype.hasOwnProperty.call(obj, key)) {
      const newKeys = [...parentKeys, key];
      const value = obj[key];
      // 如果值是对象且不为 null，递归获取键
      if (typeof value === 'object' && value !== null && !Array.isArray(value)) {
        keys = keys.concat(getKeys(value as Record<string, unknown>, newKeys));
      } else {
        keys.push(newKeys.join('.')); // 使用点表示法连接嵌套键
      }
    }
  }

  return keys;
}

export const getTestData = <T>(data: T, len: number): T[] => {
  const arr: T[] = [];
  for (let i = 0; i < len; i++) {
    arr.push(data);
  }
  return arr;
};

export function isImageUrl(url: string): boolean {
  if (!url) return false;
  // 匹配最后一个点后的扩展名（忽略查询参数和哈希值）
  const extMatch = url.match(/\.([^./?#]+)(?:[?#]|$)/i);
  if (!extMatch) return false;

  const ext = extMatch[1].toLowerCase();
  const imageExtensions = ['jpeg', 'jpg', 'png', 'gif', 'bmp', 'webp', 'svg'];

  return imageExtensions.includes(ext);
}

/**
 * 将扁平数组转为树结构，并生成符合 antd Tree 的数据结构
 */
export const arrToTree1 = (data: TreeItem[], rootName = '根目录'): TreeNode[] => {
  // Step 1: 构建 id -> item 映射
  const map: ItemMap = {};
  const tree: TreeItem[] = [];

  data.forEach(item => {
    map[item.id] = { ...item, children: [] };
  });

  // Step 2: 构建树结构
  data.forEach(item => {
    const node = map[item.id];
    if (item.parentId && map[item.parentId]) {
      map[item.parentId].children!.push(node);
    } else {
      tree.push(node);
    }
  });

  // Step 3: 转为 Antd Tree 结构（带 title、key、isLeaf）
  const convertToTreeNode = (nodes: TreeItem[], _path = '0-0'): TreeNode[] =>
    nodes.map((node, _index) => {
      // const key = `${path}-${index}`;
      const key = node.id.toString();
      const children = node.children?.length ? convertToTreeNode(node.children, key) : [];

      return {
        title: node.name,
        key,
        isLeaf: children.length === 0,
        remark: node.remark,
        data: node,
        children: children.length > 0 ? children : undefined,
      };
    });

  return [
    {
      title: rootName,
      key: 'root',
      children: convertToTreeNode(tree, 'root'),
    },
  ];
};

export function strToArr(str?: string): string[] {
  if (str) {
    if (cacheMap.has(str)) {
      return cacheMap.get(str) as string[];
    }
    const result = str.split(',');
    cacheMap.set(str, result);
    return result;
  }
  return [];
}

export function strToArrImg(str?: string): ImageItem[] {
  if (str) {
    if (cacheMap.has(str)) {
      return cacheMap.get(str) as ImageItem[];
    }
    const result = str.split(',').map((item, key) => {
      return { url: item, id: key, status: 'done' };
    });
    cacheMap.set(str, result);
    return result;
  }
  return [];
}

/**
 * 文件下载工具函数
 */
export const downloadUtils = {
  /**
   * 从响应中下载文件
   * @param response 响应对象
   * @param filename 文件名（可选，会尝试从响应头获取）
   */
  async downloadFromResponse(response: Response, filename?: string): Promise<void> {
    try {
      const blob = await response.blob();

      // 尝试从响应头获取文件名
      if (!filename) {
        const contentDisposition = response.headers.get('content-disposition');
        if (contentDisposition) {
          const filenameMatch = contentDisposition.match(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/);
          if (filenameMatch && filenameMatch[1]) {
            filename = filenameMatch[1].replace(/['"]/g, '');
          }
        }
      }

      // 创建下载链接
      const url = window.URL.createObjectURL(blob);
      const link = document.createElement('a');
      link.href = url;
      link.download = filename || 'download';

      // 触发下载
      document.body.appendChild(link);
      link.click();

      // 清理
      document.body.removeChild(link);
      window.URL.revokeObjectURL(url);
    } catch (error) {
      console.error('文件下载失败:', error);
      throw error;
    }
  },

  /**
   * 获取文件的 Blob URL
   * @param response 响应对象
   * @returns Blob URL
   */
  async getBlobUrl(response: Response): Promise<string> {
    const blob = await response.blob();
    return window.URL.createObjectURL(blob);
  },

  /**
   * 获取文件的 ArrayBuffer
   * @param response 响应对象
   * @returns ArrayBuffer
   */
  async getArrayBuffer(response: Response): Promise<ArrayBuffer> {
    return await response.arrayBuffer();
  },
  deCodeArrayBuffer(data: any) {
    const decoder = new TextDecoder('utf-8');
    const text = decoder.decode(data);
    const decodedData = text ? JSON.parse(text) : {};
    return decodedData;
  },
};

export function copyToClipboard(content) {
  let textToCopy;

  // 处理不同类型的输入内容
  if (content === null || content === undefined) {
    return Promise.reject(new Error('不能复制null或undefined'));
  } else if (typeof content === 'object') {
    // 处理对象类型，转换为格式化的JSON字符串
    try {
      textToCopy = JSON.stringify(content, null, 4);
    } catch (err) {
      return Promise.reject(new Error('对象无法转换为JSON字符串'));
    }
  } else if (typeof content === 'string') {
    // 处理字符串类型
    textToCopy = content;
  } else {
    // 处理其他基本类型（数字、布尔等）
    textToCopy = String(content);
  }

  // 验证最终要复制的文本
  if (textToCopy.trim() === '') {
    return Promise.reject(new Error('没有可复制的内容'));
  }

  // 现代浏览器：使用Clipboard API
  if (navigator.clipboard && window.isSecureContext) {
    return navigator.clipboard
      .writeText(textToCopy)
      .then(() => {
        window.$message.success('复制成功');
        return true;
      })
      .catch(err => {
        window.$message.error('复制失败');
        console.error('Clipboard API复制失败:', err);
        return false;
      });
  }

  // 兼容处理：使用textarea元素
  const textarea = document.createElement('textarea');
  textarea.value = textToCopy;

  // 设置样式使其在页面中不可见但可被选中
  textarea.style.position = 'absolute';
  textarea.style.width = '1px';
  textarea.style.height = '1px';
  textarea.style.padding = '0';
  textarea.style.margin = '-1px';
  textarea.style.overflow = 'hidden';
  textarea.style.border = '0';
  textarea.style.left = '-9999px';

  document.body.appendChild(textarea);

  // 选中内容
  textarea.select();
  textarea.setSelectionRange(0, textToCopy.length); // 兼容移动设备

  let success = false;
  try {
    // 执行复制命令
    success = document.execCommand('copy');
    window.$message.success('复制成功');
  } catch (err) {
    console.error('execCommand复制失败:', err);
    window.$message.error('复制失败');
  }

  // 清理临时元素
  document.body.removeChild(textarea);

  return Promise.resolve(success);
}
